package com.cloud.wms.service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.os.Vibrator;
import android.util.Log;

import com.cloud.core.config.EventConfig;
import com.cloud.core.eventBus.Event;
import com.cloud.core.eventBus.EventBusUtil;
import com.cloud.printer.FineExPrinter;
import com.cloud.printer.Port;
import com.cloud.printer.Printer;
import com.cloud.wms.R;
import com.cloud.wms.app.FineExApplication;
import com.cloud.wms.config.SpKey;
import com.cloud.wms.tools.RxUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

import es.dmoral.toasty.Toasty;
import io.reactivex.Observable;


/**
 * @Author： Chen
 * @Date： 2020/6/23
 * @Desc：
 */
public class PrinterService extends Service {
    public static final int MAX_POLL_COUNT = 10;
    public static final String PRINT_INFO = "PRINT_INFO";
    private String CHANNEL_ONE_ID = "1001";
    private CharSequence CHANNEL_ONE_NAME = "WMS";
    private CopyOnWriteArraySet<Printer> printInfoQueue = new CopyOnWriteArraySet<>();
    private boolean isEnd;
    private Thread thread;
    private int pollCount = 0;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        EventBusUtil.register(this);

        Notification.Builder builder = new Notification.Builder(this.getApplicationContext())
                .setSmallIcon(R.mipmap.ic_launcher_logo) // 设置状态栏内的小图标
                .setContentTitle(getResources().getString(R.string.app_name))
                .setContentText("打印服务已启动") // 设置上下文内容
                .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            //修改安卓8.1以上系统报错
            NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.enableLights(false);//如果使用中的设备支持通知灯，则说明此通知通道是否应显示灯
            notificationChannel.setShowBadge(false);//是否显示角标
            notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            manager.createNotificationChannel(notificationChannel);
            builder.setChannelId(CHANNEL_ONE_ID);
        }


        Notification notification = builder.build(); // 获取构建好的Notification
        notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
        startForeground(1, notification);

        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!isEnd) {
                    try {
                        if (pollCount >= MAX_POLL_COUNT) stopSelf();
                        Log.d("FineEx", "打印服务工作中。。。");
                        if (printInfoQueue.isEmpty()) {
                            pollCount++;
                            Thread.sleep(1000);
                            continue;
                        }
                        Printer printer = printInfoQueue.iterator().next();
                        FineExPrinter fineExPrinter = FineExApplication.component().printer();
                        if (BluetoothAdapter.getDefaultAdapter().isDiscovering())
                            BluetoothAdapter.getDefaultAdapter().cancelDiscovery();

                        fineExPrinter.close();
                        fineExPrinter.initPrinter(FineExApplication.component().kv().getString(SpKey.PRINT_DEVICE, ""));
                        if (!fineExPrinter.open(FineExPrinter.PRINTER_TYPE.ULT113x)) {
                            alert("打印机打开失败", printer);
                            break;
                        }

                        if (!fineExPrinter.wakeUp()) {
                            alert("打印机唤醒失败", printer);
                            break;
                        }
                        if (fineExPrinter.getPortState() != Port.PORT_STATE.PORT_OPEND) {
                            alert("蓝牙错误", printer);
                            break;
                        }
                        boolean printerState = fineExPrinter.getPrinterState(3000);
                        if (!printerState) {
                            alert("获取打印机状态失败", printer);
                            break;
                        }
                        if (fineExPrinter.printerInfo.isCoverOpen) {
                            alert("打印机纸仓盖未关闭", printer);
                            break;
                        }
                        if (fineExPrinter.printerInfo.isNoPaper) {
                            alert("打印机缺纸", printer);
                            break;
                        }
                        printer.print(fineExPrinter);
                        while (true) {
                            Log.d("FineEx", "打印中。。。");
                            Thread.sleep(100);
                            //此处的读超时需要算上打印内容的时间。请根据打印内容调整,如果你打印的内容更多，就需要设置更多的时间。
                            if (!fineExPrinter.getPrinterState(3000)) {
                                Thread.sleep(100);
                                continue;
                            }
                            if (fineExPrinter.printerInfo.isPrinting) {
                                Thread.sleep(100);
                            } else {
                                printInfoQueue.remove(printer);
                                break;
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        alert("打印异常错误", printInfoQueue.iterator().next());
                        break;
                    }
                }
            }
        });
        thread.start();
    }

    private void alert(String msg, Printer printer) {
        printInfoQueue.remove(printer);
        EventBusUtil.sendEvent(new Event<String>(EventConfig.PRINT_MESSAGE, msg));
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            ArrayList<Printer> printerInfoList = intent.getParcelableArrayListExtra(PRINT_INFO);
            printInfoQueue.addAll(printerInfoList);
        }
        return START_NOT_STICKY;
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onEventCome(Event event) {
        if (event == null) {
            return;
        }
        switch (event.getCode()) {
            case EventConfig.PRINT_MESSAGE:
                Observable.just("打印失败提示：" + event.getData().toString() + "，请检查后补打。")
                        .compose(RxUtils.threadSwitch())
                        .subscribe(s -> {
                            Toasty.info(this, s).show();
                            stopSelf();
                        });
                break;
        }
    }

    public boolean shockAlert(int duration) {
        if (duration <= 0) duration = 1000;
        Vibrator vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
        if (vibrator == null) return false;
        vibrator.vibrate(duration);
        return true;
    }

    public static void startPrintService(Context context, ArrayList<Printer> printInfoEntities) {
        Intent intent = new Intent();
        intent.setClass(context, PrinterService.class);
        intent.putExtra(PRINT_INFO, printInfoEntities);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //android8.0以上通过startForegroundService启动service
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }
    }

    public static void stopPrintService(Context context) {
        Intent intent = new Intent();
        intent.setClass(context, PrinterService.class);
        context.stopService(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isEnd = true;
        stopForeground(true);// 停止前台服务--参数：表示是否移除之前的通知
        EventBusUtil.unregister(this);
    }
}
